<?php


App::import('Model', 'WorkflowWorkflow');
App::import('Vendor', 'CakeWorkflowExecution');

class WfController extends AppController{
    var $name="Wf";
    var $helpers=array('Html','Form');

    function index(){

    }
    
    function create(){
        try{
            //Creates and saves the workflow definition
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $workflow = new ezcWorkflow( 'Test' );
            $initNode = new ezcWorkflowNodeVariableSet(array('init' => 'testValue'));
            $input = new ezcWorkflowNodeInput(
                    array( 'choice' => new ezcWorkflowConditionIsBool )
            );

            $workflow->startNode->addOutNode( $initNode );
            $initNode->addOutNode($input);
            $branch = new ezcWorkflowNodeExclusiveChoice;
            $branch->addInNode( $input );
            $trueNode = new ezcWorkflowNodeAction( array( 'class' => 'MyServiceTestObject',
             'arguments' => array( 'message: TRUE' ) )
            );
            $falseNode = new ezcWorkflowNodeAction( array( 'class' => 'MyServiceTestObject',
             'arguments' => array( 'message: FALSE' ) )
            );

            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'choice', new ezcWorkflowConditionIsTrue ),
                    $trueNode );
            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'choice', new ezcWorkflowConditionIsFalse ),
                    $falseNode
            );
            $merge = new ezcWorkflowNodeSimpleMerge;
            $merge->addInNode( $trueNode );
            $merge->addInNode( $falseNode );
            $merge->addOutNode( $workflow->endNode );
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $this->Definition->save($workflow);
            unset($this->Definition);
            ClassRegistry::flush();
            $this->Session->setFlash('El workflow se guardó correctamente.');
            $this->redirect(array('action' => 'index'));
        }catch (Exception $e){
            echo 'Error raised';
            echo $e->getMessage();
        }
    }
    function init(){
        try{

            //Loading from db and Execution
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $workflow = $this->Definition->loadByName('Test',1);
            $execution = new CakeWorkflowExecution();
            $execution->workflow = $workflow;
            $id = $execution->start();
            $this->_assertEqual(1,count($execution->getActivatedNodes()));
            $this->_assertTrue($execution->isSuspended());
            //At this point the execution is automatically suspended waiting for an input varible "choice"
            unset($this->Definition);
            ClassRegistry::flush();
            $this->Session->setFlash('El workflow se inició correctamente. (Suspendido)');
            $this->redirect(array('action' => 'index'));
        }catch (Exception $e){
            echo 'Error raised';
            echo $e->getMessage();
        }
    }

    function next(){
        try{
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            //Now lets create another execution and make it go to the end
            $execution = new CakeWorkflowExecution();
            $execution->workflow = $this->Definition->loadByName('Test',1);
            $id = $execution->start();
            $this->_assertEqual('choice',key($execution->getWaitingFor()));
            $execution->resume(array('choice' => true));
            $this->_assertTrue($execution->hasEnded());
            //Now let's check again that the execution is not in the database anymore
            try {
                    $execution = new CakeWorkflowExecution($id);
            } catch (Exception $e) {
                    //Exception becuase the execution has ended
                    //echo 'Exeption throw:'.$e->getMessage();
            }
            unset($this->Definition);
            ClassRegistry::flush();
            $this->Session->setFlash('El workflow finalizó su ejecución correctamente. ('.$id.')');
            $this->redirect(array('action' => 'index'));
        }catch (Exception $e){
            echo 'Error raised';
            echo $e->getMessage();
        }
    }

    function _todo(){
        try{
            //Creates and saves the workflow definition
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $workflow = new ezcWorkflow( 'Test' );
            $initNode = new ezcWorkflowNodeVariableSet(array('init' => 'testValue'));
            $input = new ezcWorkflowNodeInput(
                    array( 'choice' => new ezcWorkflowConditionIsBool )
            );

            $workflow->startNode->addOutNode( $initNode );
            $initNode->addOutNode($input);
            $branch = new ezcWorkflowNodeExclusiveChoice;
            $branch->addInNode( $input );
            $trueNode = new ezcWorkflowNodeAction( array( 'class' => 'MyServiceTestObject',
             'arguments' => array( 'message: TRUE' ) )
            );
            $falseNode = new ezcWorkflowNodeAction( array( 'class' => 'MyServiceTestObject',
             'arguments' => array( 'message: FALSE' ) )
            );

            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'choice', new ezcWorkflowConditionIsTrue ),
                    $trueNode );
            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'choice', new ezcWorkflowConditionIsFalse ),
                    $falseNode
            );
            $merge = new ezcWorkflowNodeSimpleMerge;
            $merge->addInNode( $trueNode );
            $merge->addInNode( $falseNode );
            $merge->addOutNode( $workflow->endNode );
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $this->Definition->save($workflow);

            //Loading from db and Execution
            $this->Definition = ClassRegistry::init('WorkflowWorkflow');
            $workflow = $this->Definition->loadByName('Test',1);
            $execution = new CakeWorkflowExecution();
            $execution->workflow = $workflow;
            $id = $execution->start();
            $this->_assertEqual(1,count($execution->getActivatedNodes()));
            $this->_assertTrue($execution->isSuspended());
            //At this point the execution is automatically suspended waiting for an input varible "choice"
            //Lets resume it from anther excecution object
            $execution = new CakeWorkflowExecution($id);
            $this->_assertEqual('testValue',$execution->getVariable('init'));
            $waitingFor = $execution->getWaitingFor();
            $this->_assertEqual('choice',key($execution->getWaitingFor()));
            //Let's cancell it
            $execution->cancel();
            // And try to resume it again
            try {
                    $execution = new CakeWorkflowExecution($id);
            } catch (Exception $e) {
                    //Exception becuase the execution was cancelled
                    //echo 'Exeption throw: '.$e->getMessage();
            }

            //Now lets create another execution and make it go to the end
            $execution = new CakeWorkflowExecution();
            $execution->workflow = $this->Definition->loadByName('Test',1);
            $id = $execution->start();
            $this->_assertEqual('choice',key($execution->getWaitingFor()));
            $execution->resume(array('choice' => true));
            $this->_assertTrue($execution->hasEnded());

            //Now let's check again that the execution is not in the database anymore
            try {
                    $execution = new CakeWorkflowExecution($id);
            } catch (Exception $e) {
                    //Exception becuase the execution has ended
                    //echo 'Exeption throw:'.$e->getMessage();
            }



            unset($this->Definition);
            ClassRegistry::flush();
            $b='<br/>Ok from controllers exec function';
            echo $b;

        }catch (Exception $e){
            echo 'Error raised';
            echo $e->getMessage();
        }
    }

    function _assertEqual($val1,$val2){
        if($val1!=$val2){
            throw new Exception('Assert false');
        }
    }

    function _assertTrue($val){
        if(!$val){
            throw new Exception('Assert false');
        }
    }
}

class MyServiceTestObject implements ezcWorkflowServiceObject {
	private $message;

 	public function __construct( $message ) {
		$this->message = $message;
	}

	public function execute( ezcWorkflowExecution $execution ) {
		$execution->setVariable( 'choice', true );
		return true;
	}

	public function __toString() {
		return "MyServiceTestObject, message {$this->message}";
	}
}
?>
